#include "include/common/monitoring/alerting.h"
#include <sstream>
#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>

#ifdef HAS_CURL
#include <curl/curl.h>
#endif

// 跨平台的localtime函数
inline void portable_localtime(const time_t* timer, struct tm* buf) {
#if defined(_WIN32) || defined(_WIN64)
    localtime_s(buf, timer);
#else
    localtime_r(timer, buf);
#endif
}

// Alert实现
Alert::Alert(const std::string& name, const std::string& description, AlertLevel level, 
             const std::string& source, const std::unordered_map<std::string, std::string>& labels)
    : name(name), description(description), level(level), source(source), labels(labels),
      timestamp(std::chrono::system_clock::now()) {}

// EmailNotifier实现
EmailNotifier::EmailNotifier(const std::string& smtpServer, int smtpPort, 
                           const std::string& username, const std::string& password,
                           const std::vector<std::string>& recipients)
    : smtpServer_(smtpServer), smtpPort_(smtpPort), username_(username),
      password_(password), recipients_(recipients) {}

bool EmailNotifier::notify(const Alert& alert) {
    // 此处应当使用SMTP库（如libcurl）发送邮件
    // 以下为示例代码，实际应用应当根据项目依赖进行调整
    
    // 构造邮件内容
    std::stringstream ss;
    
    // 获取当前时间的字符串表示
    auto time = std::chrono::system_clock::to_time_t(alert.timestamp);
    struct tm tm_time;
    portable_localtime(&time, &tm_time);

    ss << "Alert: " << alert.name << "\n";
    ss << "Level: ";
    
    switch (alert.level) {
    case AlertLevel::INFO:
        ss << "INFO";
        break;
    case AlertLevel::WARNING:
        ss << "WARNING";
        break;
    case AlertLevel::ERROR:
        ss << "ERROR";
        break;
    case AlertLevel::CRITICAL:
        ss << "CRITICAL";
        break;
    }
    
    ss << "\n";
    ss << "Time: " << std::put_time(&tm_time, "%Y-%m-%d %H:%M:%S") << "\n";
    ss << "Source: " << alert.source << "\n";
    ss << "Description: " << alert.description << "\n";
    
    if (!alert.labels.empty()) {
        ss << "Labels: \n";
        for (const auto& label : alert.labels) {
            ss << "  " << label.first << ": " << label.second << "\n";
        }
    }
    
    std::string emailBody = ss.str();
    
    // 以下为发送邮件的示例代码，需要根据实际情况调整
    std::cout << "Sending email alert:\n" << emailBody << std::endl;
    
    // 在实际应用中，可以使用libcurl等库来发送邮件
    // 这里简单返回true表示发送成功
    return true;
}

std::string EmailNotifier::getName() const {
    return "Email Notifier";
}

// WebhookNotifier实现
WebhookNotifier::WebhookNotifier(const std::string& webhookUrl)
    : webhookUrl_(webhookUrl) {}

#ifdef HAS_CURL
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* s) {
    size_t newLength = size * nmemb;
    try {
        s->append((char*)contents, newLength);
    } catch(std::bad_alloc& e) {
        // 处理内存分配失败
        return 0;
    }
    return newLength;
}
#endif

bool WebhookNotifier::notify(const Alert& alert) {
    // 构建JSON负载
    std::stringstream ss;
    ss << "{";
    ss << "\"name\":\"" << alert.name << "\",";
    ss << "\"description\":\"" << alert.description << "\",";
    
    ss << "\"level\":\"";
    switch (alert.level) {
    case AlertLevel::INFO:
        ss << "INFO";
        break;
    case AlertLevel::WARNING:
        ss << "WARNING";
        break;
    case AlertLevel::ERROR:
        ss << "ERROR";
        break;
    case AlertLevel::CRITICAL:
        ss << "CRITICAL";
        break;
    }
    ss << "\",";
    
    ss << "\"source\":\"" << alert.source << "\",";
    
    // 添加时间戳
    auto time = std::chrono::system_clock::to_time_t(alert.timestamp);
    struct tm tm_time;
    portable_localtime(&time, &tm_time);
    char timeBuffer[30];
    strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%dT%H:%M:%SZ", &tm_time);
    ss << "\"timestamp\":\"" << timeBuffer << "\",";
    
    // 添加标签
    ss << "\"labels\":{";
    bool first = true;
    for (const auto& label : alert.labels) {
        if (!first) {
            ss << ",";
        }
        ss << "\"" << label.first << "\":\"" << label.second << "\"";
        first = false;
    }
    ss << "}";
    
    ss << "}";
    
    std::string jsonPayload = ss.str();
    
#ifdef HAS_CURL
    // 使用libcurl发送POST请求
    CURL* curl = curl_easy_init();
    if (!curl) {
        return false;
    }
    
    // 设置curl选项
    curl_easy_setopt(curl, CURLOPT_URL, webhookUrl_.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonPayload.c_str());
    
    // 设置请求头
    struct curl_slist* headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    
    // 设置接收响应的回调
    std::string responseString;
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseString);
    
    // 执行请求
    CURLcode res = curl_easy_perform(curl);
    
    // 清理
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    
    // 检查结果
    if (res != CURLE_OK) {
        std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        return false;
    }
    
    return true;
#else
    // 没有CURL支持时，只输出到控制台
    std::cout << "Webhook notification (CURL not available):\n" << jsonPayload << std::endl;
    std::cout << "Would send to: " << webhookUrl_ << std::endl;
    return true;
#endif
}

std::string WebhookNotifier::getName() const {
    return "Webhook Notifier";
}

// ThresholdAlertRule实现
ThresholdAlertRule::ThresholdAlertRule(const std::string& name, const std::string& description, 
                                     AlertLevel level, const std::string& source,
                                     std::function<double()> valueProvider,
                                     double threshold, 
                                     std::function<bool(double, double)> comparator)
    : name_(name), description_(description), level_(level), source_(source),
      valueProvider_(valueProvider), threshold_(threshold), comparator_(comparator) {}

bool ThresholdAlertRule::check() {
    double currentValue = valueProvider_();
    return comparator_(currentValue, threshold_);
}

Alert ThresholdAlertRule::getAlert() {
    return Alert(name_, description_, level_, source_);
}

// AlertManager实现
AlertManager& AlertManager::instance() {
    static AlertManager instance;
    return instance;
}

void AlertManager::addNotifier(std::shared_ptr<AlertNotifier> notifier) {
    std::lock_guard<std::mutex> lock(notifiersMutex_);
    notifiers_.push_back(notifier);
}

void AlertManager::addRule(std::shared_ptr<AlertRule> rule) {
    std::lock_guard<std::mutex> lock(rulesMutex_);
    rules_.push_back(rule);
}

void AlertManager::sendAlert(const Alert& alert) {
    std::lock_guard<std::mutex> lock(queueMutex_);
    alertQueue_.push(alert);
    queueCondition_.notify_one();
}

void AlertManager::start(std::chrono::seconds checkInterval) {
    checkInterval_ = checkInterval;
    running_ = true;
    
    // 启动告警处理线程
    processingThread_ = std::thread(&AlertManager::processAlerts, this);
    
    // 启动检查线程
    std::thread checkThread(&AlertManager::checkLoop, this);
    checkThread.detach(); // 分离线程，让它在后台运行
}

void AlertManager::stop() {
    running_ = false;
    queueCondition_.notify_all();
    
    if (processingThread_.joinable()) {
        processingThread_.join();
    }
}

AlertManager::~AlertManager() {
    stop();
}

void AlertManager::checkLoop() {
    while (running_) {
        // 检查所有规则
        {
            std::lock_guard<std::mutex> lock(rulesMutex_);
            for (auto& rule : rules_) {
                if (rule->check()) {
                    sendAlert(rule->getAlert());
                }
            }
        }
        
        // 休眠指定的时间
        std::this_thread::sleep_for(checkInterval_);
    }
}

void AlertManager::processAlerts() {
    while (running_) {
        Alert alert = [this] {
            std::unique_lock<std::mutex> lock(queueMutex_);
            
            // 等待队列中有告警或被停止
            queueCondition_.wait(lock, [this] { 
                return !alertQueue_.empty() || !running_; 
            });
            
            if (!running_ && alertQueue_.empty()) {
                // 正在停止且队列为空，返回一个默认构造的告警
                return Alert("", "", AlertLevel::INFO, "");
            }
            
            Alert alert = alertQueue_.front();
            alertQueue_.pop();
            return alert;
        }();
        
        // 如果正在停止且获取到的是默认告警，则退出
        if (!running_ && alert.name.empty()) {
            break;
        }
        
        // 向所有通知渠道发送告警
        std::lock_guard<std::mutex> lock(notifiersMutex_);
        for (auto& notifier : notifiers_) {
            try {
                notifier->notify(alert);
            } catch (const std::exception& e) {
                std::cerr << "Error notifying " << notifier->getName() 
                          << ": " << e.what() << std::endl;
            }
        }
    }
}

// 便捷方法实现
std::shared_ptr<AlertRule> createThresholdAlertRule(
    const std::string& name, const std::string& description, 
    AlertLevel level, const std::string& source,
    std::function<double()> valueProvider,
    double threshold,
    const std::string& comparison) {
    
    std::function<bool(double, double)> comparator;
    
    if (comparison == ">" || comparison == "gt") {
        comparator = [](double value, double threshold) { return value > threshold; };
    } else if (comparison == ">=" || comparison == "ge") {
        comparator = [](double value, double threshold) { return value >= threshold; };
    } else if (comparison == "<" || comparison == "lt") {
        comparator = [](double value, double threshold) { return value < threshold; };
    } else if (comparison == "<=" || comparison == "le") {
        comparator = [](double value, double threshold) { return value <= threshold; };
    } else if (comparison == "==" || comparison == "eq") {
        comparator = [](double value, double threshold) { return value == threshold; };
    } else if (comparison == "!=" || comparison == "ne") {
        comparator = [](double value, double threshold) { return value != threshold; };
    } else {
        // 默认使用大于运算符
        comparator = [](double value, double threshold) { return value > threshold; };
    }
    
    return std::make_shared<ThresholdAlertRule>(
        name, description, level, source, valueProvider, threshold, comparator);
} 